import controller from '../core/controller'
import { get,post } from '../core/route'
import {check_captcha, no_repeat} from '../behaviour/common';
import {checkPassword} from '../behaviour/user'
import i18n from '../core/i18n'
import Validator from '../core/validator'
import UserValidator from '../validator/user'
import {db, tran, id} from '../core/db/mysql/db'
import Query from '../core/db/mysql/query'
import md5 from 'md5'

@controller()
export default class user {
    @get('/login')
    async login(){
        let res = await this.fetch('login')
        return res
    }
    @post('/login')
    async check_login() {
        if(!await this.__todo(check_captcha, this.params.captcha)) {
            return this.setCode(1).setMsg(i18n.captcha).json()
        }
        let validator = new Validator(UserValidator)
        let res = await validator.scene('login').check(this.params)
        if(res !== true) {
            return this.setCode(1).setMsg(res).json()
        }
        if(!await this.__todo(checkPassword, this.params.username, this.params.password)) {
            return this.setCode(1).setMsg(i18n.user.login.error).json()
        }
        return this.setCode(0).setMsg(i18n.user.login.success).setUrl(this.session.url === undefined?'/ucenter':this.session.url).json()
    }
    @get('/user')
    async user() {
        return await this.fetch('user')
    }
    @get('/user/list')
    async list() {
        let where = this.params
        let records = await db(async conn => {
            let QUser = new Query(conn, 'sys_user')
            where.username !== undefined && where.username !== '' && QUser.where('username', 'like', `%${where.username}%`)
            where.email !== undefined && where.email !== '' && QUser.where('email', 'like', `%${where.email}%`)
            this.session.userid !== 1 && QUser.where('adduser', this.session.userid)
            return await QUser.page(where.page?where.page:1,15, where)
        })
        this.assign('records', records)
        this.assign('where', where)
        return this.setCode(0).setMsg(i18n.success).json()
    }

    @post('/user/add')
    async add() {
        let validator = new Validator(UserValidator)
        let res = await validator.scene('register').check(this.params)
        if(res !== true) {
            return this.setCode(1).setMsg(res).json()
        }
        return await tran(async conn => {
           if(!await this.__todo(no_repeat, conn, this.params, 'username', 'sys_user')){
               return this.setMsg(i18n.repeat.username), false
           }
           let QUser = new Query(conn, 'sys_user');
           let QUserAuth = new Query(conn, 'sys_user_auth');
           const { auths = [] } = this.params;
           delete this.params['auths'];
           try{
               this.params.adduser = this.session.userid
               //判断当前用户是否为管理员
               this.session.userid === 1 ?
                 this.params.toplevel = 0 :
                 this.session.toplevel === 0 ?
                   this.params.toplevel = this.session.userid :
                   this.params.toplevel = this.session.toplevel;
               this.params.addtime = new Date().getTime()
               this.params.password = md5(this.params.password)
               await QUser.insert(this.params)
               const uid = await id(conn);
               QUserAuth.insertAll(auths.map(vo => ({ auth_id: vo, user_id: uid })));
               return this.setMsg(i18n.sys_success), true
            }catch(err) {
               console.log(err)
                return this.setMsg(i18n.sys_err), false
            }
        }) ? this.setCode(0).json() : this.setCode(1).json()
    }
    @post('/user/edit')
    async edit() {
        let validator = new Validator(UserValidator)
        let res = await validator.scene('edit').check(this.params)
        if(res !== true) {
            return this.setCode(1).setMsg(res).json()
        }
        return await tran(async conn => {
            let QUser = new Query(conn, 'sys_user');
            let QUserAuth = new Query(conn, 'sys_user_auth');
            const { auths = [] } = this.params;
            delete this.params['auths'];
            try{
                this.params.password === ''?
                    this.params.password = undefined :
                    this.params.password = md5(this.params.password);
                this.params.modifyuser = this.session.userid;
                this.params.modifytime = new Date().getTime();
                await QUser.where('id', this.params.id).update(_form);
                await QUserAuth.where('user_id', this.params.id).delete();
                await QUserAuth.insertAll(auths.map(vo => ({ user_id: this.params.id, auth_id: vo })));
                return this.setMsg(i18n.sys_success),true
            }catch(e) {
                console.error(e)
                return this.setMsg(i18n.sys_err), false
            }
        })?this.setCode(0).json():this.setCode(1).json()
    }
    @post('/user/del')
    async del(){
        let id = this.params.id
        return await tran(async conn => {
            let QUser = new Query(conn, 'sys_user'),
                QUserAuth = new Query(conn, 'sys_user_auth');
            try{
                await QUserAuth.where('user_id', id).delete()
                await QUser.where('id', id).delete()
                return true
            }catch(e) {
                return false
            }
        })
    }
    @post('/user/allot')
    async allot() {
        let user_id = this.params.user_id,
            auth_ids = this.params.auth_id
        let user_auth_arr = auth_ids instanceof Array?
            auth_ids.map(val => ({user_id, auth_id: val})):
            [{user_id, auth_id:auth_ids}]
        return await db(async conn => {
            let QUserAuth = new Query(conn, 'sys_user_auth')
            try{
                return await QUserAuth.insertAll(user_auth_arr), true
            }catch(e) {
                return false
            }
        })?this.setCode(0).setMsg(i18n.sys_success).json(): this.setCode(1).setMsg(i18n.sys_err).json()
    }
    @get('/user/allot')
    async allot_get() {
        let id = this.params.id
        return await db(async conn => {
            let QAuth = new Query(conn, 'sys_auth'),
                QUserAuth = new Query(conn, 'sys_user_auth')
            let authes = await QAuth.where('adduser', this.session.userid).where('status', 1).select(),
                user_authes = await QUserAuth.where('user_id', id).fields('auth_id').select()
            let userAuthSet = new Set()
            user_authes.forEach(val => {
                userAuthSet.add(val['auth_id'])
            })
            this.assign('authes', authes)
            this.assign('select_authes', [...userAuthSet])
            this.assign('user_id', id)
            return this.setCode(0).setMsg(i18n.success).json()
        })
    }

    @get('/ucenter')
    async ucenter() {
        return await this.fetch('ucenter')
    }

}
